#pragma once
#include "Socket.hpp"
#include <memory>
#include <unistd.h>
#include <functional>
#include <signal.h>

using callback_t = std::function<std::string(std::string &str)>;

class Server
{
private:
    void HanderIO(InetAddr &addr, std::shared_ptr<Socket> sockfd)
    {
        std::string inbuffer;
        ssize_t n = sockfd->Recv(&inbuffer);
        if (n > 0)
        {
            // 在这里处理客户端请求
            std::string send_str = _cb(inbuffer);
            sockfd->Send(send_str);
        }
        else if (n == 0)
        {
            LOG(LogLevel::WARNING) << "读取客户端写入完毕，退出";
        }
        else
        {
            LOG(LogLevel::ERROR) << "读取客户端写入失败，退出";
        }
        sockfd->Close();
    }

public:
    Server(uint16_t port, callback_t cb)
        : _port(port), _cb(cb), _ptr(std::make_unique<TcpSocket>())
    {
        _ptr->BuildSocket(_port);
    }
    void Run()
    {
        while (true)
        {
            signal(SIGCHLD, SIG_IGN);
            InetAddr addr;
            auto sockfd = _ptr->Accept(&addr);
            if (fork() == 0)
            {
                // 子进程
                // 关闭监听socket
                _ptr->Close();
                HanderIO(addr, sockfd);
                exit(0);
            }
            // 父进程
            // 关闭accept返回的socket
            sockfd->Close();
        }
    }
    ~Server() {}

private:
    uint16_t _port;
    callback_t _cb;
    std::unique_ptr<Socket> _ptr;
};